package mi.payment.utils.transaction;

import android.content.Context;
import android.text.TextUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import mi.payment.constants.Configs;
import mi.payment.constants.ParameterConfig;
import mi.payment.constants.ParameterConfigCache;
import mi.payment.constants.TTLV;
import mi.payment.constants.TTLVUtils;
import mi.payment.constants.TransactionBitmap;
import mi.payment.settings.MerManagerSettings;
import mi.payment.settings.MerchantSettingsOperation;
import mi.payment.settings.NetworkDataOperations;
import mi.payment.settings.NetworkParamSettings;
import mi.payment.settings.QPSParamsOperation;
import mi.payment.settings.SalesSlipPrintSettingsOperation;
import mi.payment.settings.SecurityPasswordSettingsOperation;
import mi.payment.settings.SettlementTransaction;
import mi.payment.settings.SettlementTransactionOperation;
import mi.payment.settings.SystemParamsOperation;
import mi.payment.settings.SystemParamsSettings;
import mi.payment.settings.TransactionInputPwdOperation;
import mi.payment.settings.TransactionOtherOperation;
import mi.payment.settings.TransactionSwitchOperation;
import mi.payment.utils.iso8583.EncodePackage;
import mi.payment.utils.iso8583.MsgField;
import mi.payment.utils.iso8583.Utils;
import mi.payment.utils.secure.TerminalSecure;
import sunmi.sunmiui.utils.LogUtil;

/**
 * 下载商户参数
 *
 * @author sunmi on 2017/2/17.
 */
public class MerchantParamsDownloadTask extends TransactionTask<Void, Void, String> {

    public static final String TAG = "MerchantParamsDownloadTask";

    protected MerchantParamsDownloadTask(Context context) {
        super(context, false);
    }

    @Override
    protected void onBegin(Void[] params) {
        NetworkParamSettings networkSettings = NetworkDataOperations.getInstance().getNetworkParamSettings();
        String address = networkSettings.getThirdServerIpAddress();
        String port = networkSettings.getThirdServerPort();
        if (!TextUtils.isEmpty(address)) {
            pospAccess.setServerIP(address);
        }
        if (!TextUtils.isEmpty(port)) {
            pospAccess.setServerPort(Integer.parseInt(port));
        }
    }

    @Override
    protected String appointResult() {
        return resultStr;
    }

    @Override
    protected String doTransactionSelf() {
        return resultStr;
    }

    @Override
    protected Map<String, MsgField> preAssembly() {
        return EncodePackage.preAssemblyBase(TransactionBitmap.BITMAP_MERCHANT_PARAMS_DOWNLOADED);
    }

    @Override
    protected byte[] changeAndAssembly(Map<String, MsgField> fieldMap) {
        resultStr = "FF";

        MerManagerSettings merchantParams = merchantSettingsOperation.getMerManagerSettings();
        SystemParamsSettings systemParams = mSystemParamsOperation.getSystemParamsSettings();

        MsgField f011 = fieldMap.get("F011");
        f011.setDataStr(mSystemParamsOperation.getIncrementSerialNum());

        MsgField f041 = fieldMap.get("F041");
        String terminalNum = merchantParams.getTerminalNum();
        if (TextUtils.isEmpty(terminalNum)) {
            fieldMap.remove("F041");
        } else {
            f041.setDataStr(terminalNum);
        }

        MsgField f042 = fieldMap.get("F042");
        String merchantNum = merchantParams.getMerchantNum();
        if (TextUtils.isEmpty(merchantNum)) {
            fieldMap.remove("F042");
        } else {
            f042.setDataStr(merchantNum);
        }

        MsgField f060 = fieldMap.get("F060");
        String value60 = "00" + systemParams.getBatchNumStart() + 360;
        f060.setDataStr(value60);
        f060.setDataLength(value60.length());

        return EncodePackage.assembly(fieldMap, "0800", TerminalSecure.PROCESSREQUEST_NONE);
    }

    @Override
    protected void onUnpacked(HashMap<String, MsgField> resp) {
        if (TextUtils.equals("00", resultStr)) {
            MsgField f062 = resp.get("F062");
            LogUtil.e(TAG, "  62field=null " + (f062 == null));
            if (f062 != null) {
                byte[] dataBytes = f062.getDataBytes();
                String hexString = Utils.byte2HexStr(dataBytes);
                LogUtil.e("nsz", hexString);

                ParameterConfigCache configOperation = ParameterConfigCache.getInstance();
                Map<String, TTLV> map = TTLVUtils.builderTTLVMap(hexString);
                LogUtil.e("nsz", " " + (map == null) + "");
                LogUtil.e("nsz", " " + map.size());
                for (Map.Entry<String, TTLV> entry : map.entrySet()) {
                    String key = entry.getKey().toUpperCase();
                    TTLV ttlv = entry.getValue();
                    LogUtil.e("nsz", "key = " + key + " and value = " + ttlv);
                    fillValue(configOperation, key, ttlv);
                }
                ParameterConfig config = configOperation.getParameterConfig();
                LogUtil.i("nsz", config.toString());
                String newVer = config.getParameterVersion();
                String oldVer = merManagerSettings.getTerminalParamVersion();
                if (TextUtils.equals(newVer, oldVer)) {
                    // 参数版本没有更新，不需要更新本地参数
                    LogUtil.e(TAG, "参数版本没有更新，不需要更新本地参数");
                    return;
                }
                LogUtil.e(TAG, "参数版本:" + newVer + " 开始保存终端参数...");
                merchantSettingsOperation.saveTerminalParamVersion(newVer); // 保存参数版本号

                SalesSlipPrintSettingsOperation sspOperation = SalesSlipPrintSettingsOperation.getInstance();
                SystemParamsOperation systemParamsOperation = SystemParamsOperation.getInstance();

                // 2字节扩展为16bit位图，对应16个开关：
                // 1=结算打印明细设置
                // 2=英文设置
                // 3=签购单设置（0：不打印，1：打印）
                // 4=默认交易设置（0：消费，1：预授权）
                // 5=消费撤销是否刷卡
                // 6=消费撤销是否输密
                // 7=预授权完成撤销是否刷卡
                // 8=预授权完成撤销是否输密
                // 9=预授权撤销是否输密
                // 10=预授权完成（请求）是否输密
                // 11=预授权撤销是否允许手输卡号
                // 12=预授权完成（请求）是否允许手输卡号
                TTLV ttlv09 = map.get("09");
                if (ttlv09 != null) {
                    byte[] b = Utils.hexStr2Bytes(ttlv09.getValue());
                    boolean[] binary = Utils.getBinaryFromByte(b);
                    LogUtil.e("nsz", "开关位图:" + Arrays.toString(binary));
                    if (binary != null && binary.length >= 16) {
                        // 交易输密控制
                        TransactionInputPwdOperation tipOperation = TransactionInputPwdOperation.getInstance();
                        tipOperation.saveConsumptionRevokePwd(binary[6]);
                        tipOperation.saveFieldAuthCompleteRevokePwd(binary[8]);
                        tipOperation.saveFieldAuthRevokePwd(binary[9]);
                        tipOperation.saveFieldAuthCompleteReqPwd(binary[10]);

                        // 结算交易控制
                        SettlementTransaction settlement = SettlementTransactionOperation.getInstance().getSettlementTransaction();
                        SettlementTransactionOperation settlementOperation = SettlementTransactionOperation.getInstance();
                        settlementOperation.saveSettlementTransaction(settlement);

                        // 签购单是否打印英文
                        sspOperation.saveSalesSlipPrintEnglish(binary[2]);
                    }
                }

                // 4字节扩展为32bit位图，对应32个开关：
                // 1=余额查询
                // 2=消费
                // 3=消费撤销
                // 4=预授权
                // 5=预授权撤销
                // 6=预授权完成（通知）
                // 7=预授权完成（联机）
                // 8=预授权完成撤销
                // 9=分期
                // 10=分期消费撤销
                // 11=退货
                // 12=电子现金
                // 【12-32预留】
                TTLV ttlv13 = map.get("13");
                if (ttlv13 != null) {
                    byte[] b = Utils.hexStr2Bytes(ttlv13.getValue());
                    boolean[] binary = Utils.getBinaryFromByte(b);
                    LogUtil.e("nsz", "交易功能设置:" + Arrays.toString(binary));
                    if (binary != null && binary.length >= 16) {
                        // 交易开关设置
                        TransactionSwitchOperation tsOperation = TransactionSwitchOperation.getInstance();
                        tsOperation.saveQueryBalance(binary[1]);
                        tsOperation.saveConsumption(binary[2]);
                        tsOperation.saveConsumptionRevoke(binary[3]);
                        tsOperation.saveFieldAuth(binary[4]);
                        tsOperation.saveFieldAuthRevoke(binary[5]);
                        tsOperation.saveFieldAuthCompleteRevocationNotice(binary[6]);
                        tsOperation.saveFieldAuthReq(binary[7]);
                        tsOperation.saveFieldAuthCompleteRevocation(binary[8]);
                        tsOperation.saveReturnGoods(binary[11]);
                    }
                }

                // 盛付通参数配置缓存
                ParameterConfigCache parameterConfigCache = ParameterConfigCache.getInstance();
                ParameterConfig parameterConfig = parameterConfigCache.getParameterConfig();
                if (parameterConfig != null) {
                    if (TextUtils.isEmpty(config.getTerminalNo())) {
                        parameterConfigCache.saveTerminalNo(config.getTerminalNo());
                    }
                    if (TextUtils.isEmpty(config.getMerchantNo())) {
                        parameterConfigCache.saveMerchantNo(parameterConfig.getMerchantNo());
                    }
                    if (TextUtils.isEmpty(config.getMerchantName())) {
                        parameterConfigCache.saveMerchantName(parameterConfig.getMerchantName());
                    }
                }

                // 商户管理设置
                MerchantSettingsOperation merchantOperation = MerchantSettingsOperation.getInstance();
                if (isNoEmpty(config.getMerchantNo())) {
                    merchantOperation.saveMerchantNum(config.getMerchantNo());
                }
                if (isNoEmpty(config.getTerminalNo())) {
                    merchantOperation.saveTerminalNum(config.getTerminalNo());
                }
                if (isNoEmpty(config.getMerchantName())) {
                    merchantOperation.saveMerchantName(config.getMerchantName());
                }
                if (isNoEmpty(Configs.getInstance().MERCHANT_DEFAULT_ENGLISH_NAME())) {
                    merchantOperation.saveMerchantEnglishName(Configs.getInstance().MERCHANT_DEFAULT_ENGLISH_NAME());
                }

                // 网络参数设置
                NetworkDataOperations networkOperations = NetworkDataOperations.getInstance();
                if (isNoEmpty(config.getTPDU())) {
                    networkOperations.saveTPDU(config.getTPDU());
                }
                if (isNoEmpty(config.getTransactionTimeOut())) {
                    networkOperations.saveCommunicationTimeout(config.getTransactionTimeOut());
                }
                if (isNoEmpty(config.getTransactionRetryTime())) {
                    try {
                        networkOperations.saveTransactionRepeatNum(Integer.parseInt(config.getTransactionRetryTime()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                ServerAndIp serverAndIp = parseIP(config.getServerAndPort());
                if (serverAndIp != null) {
                    if (isNoEmpty(serverAndIp.hostIpAddress)) {
                        networkOperations.saveHostIpAddress(serverAndIp.hostIpAddress);
                    }
                    if (isNoEmpty(serverAndIp.hostPort)) {
                        networkOperations.saveHostPort(serverAndIp.hostPort);
                    }
                    if (isNoEmpty(serverAndIp.spareHostIpAddress)) {
                        networkOperations.saveSpareHostIpAddress(serverAndIp.spareHostIpAddress);
                    }
                    if (isNoEmpty(serverAndIp.spareHostPort)) {
                        networkOperations.saveSpareHostPort(serverAndIp.spareHostPort);
                    }
                }

                // 安全密码设置
                SecurityPasswordSettingsOperation securityPasswordSettingsOperation = SecurityPasswordSettingsOperation.getInstance();
                if (isNoEmpty(config.getSecurePwd())) {
                    securityPasswordSettingsOperation.saveSecurityPassword(config.getSecurePwd());
                }

                // 交易管理的数据操作
                if (isNoEmpty(config.getSerialNo())) {
                    systemParamsOperation.saveSerialNumber(config.getSerialNo());
                }
                if (isNoEmpty(config.getBatchNo())) {
                    systemParamsOperation.saveBatchNumber(config.getBatchNo());
                }
                if (isNoEmpty(config.getPrintTime())) {
                    sspOperation.savePrintReceiptSingleNum(config.getPrintTime());
                }
                try {
                    if (isNoEmpty(config.getMaxTransactionTime())) {
                        systemParamsOperation.saveTransactionNumber(Integer.parseInt(config.getMaxTransactionTime()));
                    }
                    if (isNoEmpty(config.getCorrectRetryTime())) {
                        systemParamsOperation.saveCorrectFrequency(Integer.parseInt(config.getCorrectRetryTime()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // 其它交易控制类
                TransactionOtherOperation otherOperation = TransactionOtherOperation.getInstance();
                if (isNoEmpty(config.getMaxReturnGoodAmount())) {
                    try {
                        otherOperation.saveMaximumReturnAmount(Long.parseLong(config.getMaxReturnGoodAmount()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                SalesSlipPrintSettingsOperation salesSlipPrintSettingsOperation = SalesSlipPrintSettingsOperation.getInstance();
                switch (config.getIsShowLogo()) {
                    case "0": // 不显示
                        salesSlipPrintSettingsOperation.saveRise(1);
                        break;
                    case "1": // 显示
                        salesSlipPrintSettingsOperation.saveRise(2);
                        break;
                }
            }

        } else {
            resultStr = "FF";
        }

    }

    private boolean isNoEmpty(String str) {
        return !TextUtils.isEmpty(str);
    }

    private void fillValue(ParameterConfigCache configOption, String key, TTLV ttlv) {
        String type = ttlv.getType();
        String length = ttlv.getLength();
        String value = ttlv.getValue();
        int index = Integer.parseInt(length, 16);
        if (TextUtils.equals("01", type)) {
            value = value.substring(0, index);
        }
        LogUtil.e(TAG, " key " + key);
        switch (key) {
            case "00":
            case "0000":
                // 参数版本
                configOption.saveParameterVersion(value);
                break;
            case "01":
            case "0001":
                // 商户编号
                configOption.saveMerchantNo(value);
                break;
            case "02":
            case "0002":
                // 终端编号
                configOption.saveTerminalNo(TTLVUtils.decodeGBkHexString(value));
                break;
            case "03":
            case "0003":
                // 安全密码
                configOption.saveSecurePwd(value);
                break;
            case "04":
            case "0004":
                // 商户名称
                configOption.saveMerchantName(TTLVUtils.decodeGBkHexString(value));
                break;
            case "05":
            case "0005":
                // 当前时间
                configOption.saveCurrentTime(value);
                break;
            case "06":
            case "0006":
                // 流水号
                configOption.saveSerialNo(value);
                break;
            case "07":
            case "0007":
                // 批次号
                configOption.saveBatchNo(value);
                break;
            case "08":
            case "0008":
                // 最大退货金额
                configOption.saveMaxReturnGoodAmount(value);
                break;
            case "09":
            case "0009":
                // 开关位图
                configOption.saveOpenAndCloseBitmap(value);
                break;
            case "0A":
            case "000A":
                // 服务器IP、端口
                configOption.saveServerAndPort(value);
                break;
            case "0B":
            case "000B":
                // TPDU
                configOption.saveTPDU(value);
                break;
            case "0C":
            case "000C":
                // 是否预拨号
                configOption.saveIsPreCall(value);
                break;
            case "0D":
            case "000D":
                // 交易超时时间
                configOption.saveTransactionTimeOut(value);
                break;
            case "0E":
            case "000E":
                // 交易重拔次数
                configOption.saveTransactionRetryTime(value);
                break;
            case "0F":
            case "000F":
                // 外线号码
                configOption.saveOutsideNumber(value);
                break;
            case "10":
            case "0010":
                // 中心交易号码1
                configOption.saveCenterTransactionNumber1(value);
                break;
            case "11":
            case "0011":
                // 中心交易号码2
                configOption.saveCenterTransactionNumber2(value);
                break;
            case "12":
            case "0012":
                // 中心交易号码3
                configOption.saveCenterTransactionNumber3(value);
                break;
            case "13":
            case "0013":
                // 交易功能设置
                configOption.saveShieldSettings(value);
                break;
            case "14":
            case "0014":
                // 冲正重发次数
                configOption.saveCorrectRetryTime(value);
                break;
            case "15":
            case "0015":
                // 打印张数
                configOption.savePrintTime(value);
                break;
            case "16":
            case "0016":
                // 最大交易笔数
                configOption.saveMaxTransactionTime(value);
                break;
            case "17":
            case "0017":
                // 签购单备注
                configOption.saveSignRemark(TTLVUtils.decodeGBkHexString(value));
                break;
            case "18":
            case "0018":
                // 电子现金笔数
                configOption.saveElectronicCashTime(value);
                break;
            case "19":
            case "0019":
                // 是否显示盛付通logo
                LogUtil.e("lxy", "value:" + value);
                configOption.saveIsShowLogo(value);
                break;
            case "20":
            case "0020":
                // 原样打印在二维码上方的文字
                configOption.savePrintTopText(TTLVUtils.decodeGBkHexString(value));
                break;
            case "21":
            case "0021":
                // 二维码链接内容转换为二维码打印
                configOption.savePrintQRScan(TTLVUtils.decodeGBkHexString(value));
                break;
            case "22":
            case "0022":
                // 原样打印在二维码下方的文字
                configOption.savePrintBottomText(TTLVUtils.decodeGBkHexString(value));
                break;
            case "23":
            case "0023":
                // 主消费流程含插卡
                configOption.saveTransactionControl(value);
                break;
            case "24":
            case "0024":
                // 支付图标控制
                break;
            case "25":
            case "0025":
                // QPS免密限额
                QPSParamsOperation.getInstance().saveQpsParamNeedNoPswLimit(Integer.valueOf(value));
                break;
            case "26":
            case "0026":
                // 免签限额
                QPSParamsOperation.getInstance().saveQpsParamNeedNoSignLimit(Integer.valueOf(value));
                break;
            case "27":
            case "0027":
                // 双免功能控制参数
                byte[] b = Utils.hexStr2Bytes(value);
                boolean[] binary = Utils.getBinaryFromByte(b);
                LogUtil.e("nsz", "双免功能控制参数" + Arrays.toString(binary) + " length " + binary.length);
                if (binary.length >= 16) {
                    // 非接快速业务标识
                    if (binary[1]) {
                        QPSParamsOperation.getInstance().saveQpsParamNeedNoPswId(true);
                        QPSParamsOperation.getInstance().saveQpsParamBinAId(false);
                        QPSParamsOperation.getInstance().saveQpsParamBinBId(false);
                        QPSParamsOperation.getInstance().saveQpsParamCDCVMId(false);
                        QPSParamsOperation.getInstance().saveQpsParamNeedNoSignId(true);
                    } else {
                        QPSParamsOperation.getInstance().saveQpsParamNeedNoPswId(false);
                        QPSParamsOperation.getInstance().saveQpsParamBinAId(false);
                        QPSParamsOperation.getInstance().saveQpsParamBinBId(false);
                        QPSParamsOperation.getInstance().saveQpsParamCDCVMId(false);
                        QPSParamsOperation.getInstance().saveQpsParamNeedNoSignId(false);
                    }
                }
                break;
            default:
                break;
        }

    }

    private ServerAndIp parseIP(String value) {
        if (value == null) {
            return null;
        }

        ServerAndIp serverAndIp = new ServerAndIp();
        int i = 0;
        String ip = "";

        try {
            if (value.length() == 12) {
                for (int j = 0; j < 4; j++) {
                    if (i != 3) {
                        ip += Integer.parseInt(value.substring(i, i + 2), 16) + ".";
                    } else {
                        ip += String.valueOf(Integer.parseInt(value.substring(i, i + 2), 16));
                    }
                    i += 2;
                }
                serverAndIp.hostIpAddress = ip;
                serverAndIp.hostPort = String.valueOf(Integer.parseInt(value.substring(i, i + 4), 16));
                return serverAndIp;

            } else if (value.length() == 24) {
                for (int j = 0; j < 4; j++) {
                    if (j != 3) {
                        ip += Integer.parseInt(value.substring(i, i + 2), 16) + ".";
                    } else {
                        ip += String.valueOf(Integer.parseInt(value.substring(i, i + 2), 16));
                    }
                    i += 2;
                }
                serverAndIp.hostIpAddress = ip;
                serverAndIp.hostPort = String.valueOf(Integer.parseInt(value.substring(i, i + 4), 16));
                i += 4;

                ip = "";
                for (int j = 0; j < 4; j++) {
                    if (j != 3) {
                        ip += Integer.parseInt(value.substring(i, i + 2), 16) + ".";
                    } else {
                        ip += String.valueOf(Integer.parseInt(value.substring(i, i + 2), 16));
                    }
                    i += 2;
                }
                serverAndIp.spareHostIpAddress = ip;
                serverAndIp.spareHostPort = String.valueOf(Integer.parseInt(value.substring(i, i + 4), 16));

                return serverAndIp;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private class ServerAndIp {
        String hostIpAddress;       // 主机Ip地址
        String hostPort;            // 主机端口
        String spareHostIpAddress;  // 备份服务器IP
        String spareHostPort;       // 备份服务器端口port
    }

}
